package com.yuan.spring.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * * application 方法封装
 * Created by 袁恩光 on 2017/12/9.
 */
@Component
public class ApplicationUtil implements ApplicationContextAware {

    private static ApplicationContext CONTEXT;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        CONTEXT = applicationContext;
    }

    /**
     * 动态注册bean 方法
     *
     * @param tClass   注册的class
     * @param beanName bean名称
     * @param args     构造方法参数
     */
    public static <T> T registerBean(Class<T> tClass, String beanName, Object... args) {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) CONTEXT.getAutowireCapableBeanFactory();
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(tClass);
        for (Object object : args) {
            beanDefinitionBuilder.addConstructorArgValue(object);
        }
        defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        return CONTEXT.getBean(beanName, tClass);
    }

    public static <T> T getBean(Class<T> tClass){
        return CONTEXT.getBean(tClass);
    }

    public static Map<String,Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType){
        return CONTEXT.getBeansWithAnnotation(annotationType);
    }

}
